package com.guodi.model.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.guodi.common.constant.StatusCode;
import com.guodi.common.exception.BaseRuntimeException;
import com.guodi.common.utils.*;
import com.guodi.core.boot.ctrl.BaseController;
import com.guodi.core.secure.LoginUser;
import com.guodi.core.secure.utils.AuthUtil;
import com.guodi.map.feign.IMapClient;
import com.guodi.model.constant.IdtIndicatorsConst;
import com.guodi.model.entity.*;
import com.guodi.model.service.*;
import com.guodi.model.utils.ExcelUtil;
import com.guodi.model.utils.RegularUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;
import javax.annotation.Resource;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import springfox.documentation.annotations.ApiIgnore;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @描述：指标信息表控制类
 * @作者: 彭辉
 * @日期: 2020-06-05
 */

@RestController
@RequestMapping("/IdtIndicators")
@Api(value = "API - IdtIndicatorsController", tags = "指标信息表")
public class IdtIndicatorsController extends BaseController {

    @Resource
    private IIdtIndicatorsService idtIndicatorsService;

    @Resource
    private IIdtYearRelevanceService iIdtYearRelevanceService;

    @Resource
    private IIdtTargetValueService iIdtTargetValueService;

    @Resource
    private IIdtIndicatorsService iIdtIndicatorsService;

    @Resource
    private IMdlModelResultService iMdlModelResultService;

    @Resource
    private IIdtMonitorValueService iIdtMonitorValueService;

    @Resource
    private IIdtWarnRuleService iIdtWarnRuleService;

    @Resource
    private IIdtReportValueService idtReportValueService;

    @Resource
    private IRedisDictService iRedisDictService;

    /**
     * @描述: 根据实体属性分页查询
     * @入参:
     * @出参:
     * @作者: 彭辉
     * @日期: 2020-06-05
     **/
    @PostMapping("/listByEntity")
    @ApiOperation(value = " 根据实体属性分页查询")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "current", value = "当前页码", required = true, dataType = "long", paramType = "query", example = "1"),
            @ApiImplicitParam(name = "size", value = "每页显示数量", required = true, dataType = "long", paramType = "query", example = "10"),
            @ApiImplicitParam(name = "name", value = "名称检索", required = false, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "datasource", value = "数据来源(指标填报传:hand)", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "type", value = "指标类型", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "sort", value = "排序字段", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "sortWay", value = "排序方式", required = true, dataType = "string", paramType = "query")
    })
    public AjaxResult listByEntity(@ApiIgnore Page page, @ApiIgnore IdtIndicators idtIndicators) {
        QueryWrapper<IdtIndicators> wrapper = new QueryWrapper();
        // 设置分页查询条件
        this.queryConditions(wrapper, idtIndicators);
        if (StringUtils.isNotBlank(idtIndicators.getType())) {
            wrapper.eq("type", idtIndicators.getType());
        }
        IPage<IdtIndicators> iPage = idtIndicatorsService.page(page, wrapper);
        List<IdtIndicators> list = iPage.getRecords();

        // 获取复合指标
        LambdaQueryWrapper<IdtIndicators> lambdaQueryWrapper = (new QueryWrapper()).lambda();
        lambdaQueryWrapper.eq(IdtIndicators::getDatasource, "formula");
        List<IdtIndicators> formulaList = idtIndicatorsService.list(lambdaQueryWrapper);
        Map<String, List<String>> tipMap = new HashMap<>();
        for (IdtIndicators res : list) {
            for (IdtIndicators idt : formulaList) {
                if (StringUtils.isNotBlank(idt.getCalculateResult()) && idt.getCalculateResult().indexOf(res.getCode()) != -1) {
                    if (tipMap.get(res.getId()) == null) {
                        List<String> tipList = new ArrayList<>();
                        tipMap.put(res.getId(), tipList);
                    }
                    tipMap.get(res.getId()).add(idt.getName());
                }
            }
        }

        for (IdtIndicators res : list) {
            List<String> tipList = tipMap.get(res.getId());
            if (tipList != null && tipList.size() > 0) {
                res.setTips(String.join(",", tipList));
            }
        }

        // 匹配行政区划名称时，不走字典的redis缓存取值，查询map_division(行政区划表)获取对应的行政区划名称
        /*PageData pageData = new PageData();
        List<PageData> divisionList = planStatusQuoService.listDivisionByEntity(pageData);
        Map<String, String> dictMap = new HashMap<>();
        for (PageData data : divisionList) {
            dictMap.put(data.get("code").toString(), data.get("name").toString());
        }
        for (IdtIndicators indicators : list) {
            // indicators.setDivisionName(iRedisDictService.getText(IdtIndicatorsConst.DICT_QYDM, divisionCode));
            String divisionCode = indicators.getDivisionCode().indexOf("00") == -1 ? indicators.getDivisionCode() : indicators.getDivisionCode().substring(0, indicators.getDivisionCode().indexOf("00"));
            indicators.setDivisionName(dictMap.get(divisionCode));
        }*/
        return new AjaxResult(iPage);
    }

    /**
     * @描述: 根据主键查询
     * @入参:
     * @出参:
     * @作者: 彭辉
     * @日期: 2020-06-05
     **/
    @PostMapping("/findById")
    @ApiOperation(value = "根据主键查询")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "ID", required = true,
                    dataType = "string", paramType = "query")
    })
    public AjaxResult findById(String id) {
        if (StringUtils.isBlank(id)) {
            return new AjaxResult(StatusCode.ERROR_CODE_40005, "id不能为空");
        }
        IdtIndicators idtIndicators = idtIndicatorsService.getById(id);
        return new AjaxResult(idtIndicators);
    }

    /**
     * @描述: 查询指标项编号是否唯一
     * @入参:
     * @出参:
     * @作者: 彭辉
     * @日期: 2020-06-05
     **/
    @PostMapping("/hasCode")
    @ApiOperation(value = "查询指标项编号是否唯一")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "ID", required = false,
                    dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "code", value = "编号", required = true,
                    dataType = "string", paramType = "query")
    })
    public AjaxResult hasCode(@ApiIgnore IdtIndicators idtIndicators) {
        AjaxResult ajaxResult = new AjaxResult();
        if (StringUtils.isBlank(idtIndicators.getCode())) {
            return new AjaxResult(StatusCode.ERROR_CODE_40005, "code不能为空");
        }
        LambdaQueryWrapper<IdtIndicators> wrapper = new QueryWrapper().lambda();
        wrapper.eq(IdtIndicators::getCode, idtIndicators.getCode());
        IdtIndicators indicators = idtIndicatorsService.getOne(wrapper);
        if (indicators != null && !indicators.getId().equals(idtIndicators.getId())) {
            ajaxResult.setData(true);// 存在
        } else {
            ajaxResult.setData(false);// 不存在
        }
        return ajaxResult;
    }

    /**
     * @描述: 查询指标项名称是否唯一
     * @入参:
     * @出参:
     * @作者: 彭辉
     * @日期: 2020-06-05
     **/
    @PostMapping("/hasName")
    @ApiOperation(value = "查询指标项名称是否唯一")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "ID", required = false, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "name", value = "名称", required = true, dataType = "string", paramType = "query")
    })
    public AjaxResult hasName(String name, String id) {
        boolean hasName = this.idtIndicatorsService.hasName(name, id);
        return new AjaxResult(hasName);
    }

    /**
     * @描述: 验证指标预警规则表达式是否正确
     * @入参:
     * @出参:
     * @作者: 代鹏刚
     * @日期: 2021/7/30 17:09
     **/
    @PostMapping("/checkExpression")
    @ApiOperation(value = "验证指标预警规则表达式是否正确")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "expression", value = "表达式", required = true, dataType = "string", paramType = "query")
    })
    public AjaxResult checkExpression(String expression) {
        try {
            expression = StringEscapeUtils.unescapeXml(expression).replaceAll("\"", "").replaceAll("%", "").replaceAll("([^=><])=([^=><])", "==");
            expression = expression.replaceAll("&nbsp;", "");
            ScriptEngineManager manager = new ScriptEngineManager();
            ScriptEngine engine = manager.getEngineByName("js");
            // 每次保存时验证表达式是否正确，设置初始值1.1
            engine.put("TargetValue", 1.1);
            engine.put("AvgMonitorValue", 1.1);
            engine.put("LastMonitorValue", 1.1);
            engine.put("MonitorValue", 1.1);
            engine.put("BaseValue", 1.1);
            Object result = engine.eval(expression);
            return new AjaxResult(result);
        } catch (Exception e) {
            e.printStackTrace();
            return new AjaxResult(StatusCode.ERROR_CODE_40005, "规则配置有误，请检查");
        }
    }

    /**
     * @描述: 新增
     * @入参:
     * @出参:
     * @作者: 彭辉
     * @日期: 2020-06-05
     **/
    @PostMapping("/save")
    @ApiOperation(value = "新增")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult save(IdtIndicators idtIndicators) {
        // 2021-12-10 陈宏成 判断是否指标重名
        boolean hasName = this.idtIndicatorsService.hasName(idtIndicators.getName(), idtIndicators.getId());
        if (hasName) {
            return new AjaxResult(StatusCode.ERROR_CODE_40005, "该指标名称已存在，请修改指标名称。");
        }
        // 20210804 新增指标预警规则字段
        if (StringUtils.isNotBlank(idtIndicators.getWarnRuleConfig())) {
            idtIndicators.setWarnRuleConfig(StringEscapeUtils.unescapeXml(idtIndicators.getWarnRuleConfig()));
        }
        // 20230424 新增评估规则配置字段
        if (StringUtils.isNotBlank(idtIndicators.getEstimateRuleConfig())) {
            idtIndicators.setEstimateRuleConfig(StringEscapeUtils.unescapeXml(idtIndicators.getEstimateRuleConfig()));
        }
        idtIndicators.setId(UuidUtil.get32UUID());
        // 处理行政区划代码位数问题
        // 2020-12-26前端屏蔽行政区划字段 汤厚韬
        // idtIndicators.setDivisionCode(idtIndicators.getDivisionCode().length() == 2 ? idtIndicators.getDivisionCode() + "0000" : idtIndicators.getDivisionCode().length() == 4 ? idtIndicators.getDivisionCode() + "00" : idtIndicators.getDivisionCode());
        // 设置指标所属机构
        idtIndicators.setOrgId(this.getUser().getDeptId());
        prepareData(idtIndicators, true);
        //如果数据来源于模型结果，则遍历更新该指标对应指标数值
        if (idtIndicators.getDatasource().equals("model")) {
            //获取预警规则
            IdtWarnRule warnRule = iIdtWarnRuleService.getById(idtIndicators.getWarnRuleId());
            if (warnRule == null) {
                return new AjaxResult(StatusCode.ERROR_CODE_40005, "该指标对预警规则为空!");
            }
            // 根据数据类型选择更新的指标数值
            if (idtIndicators.getDataType().equals("monitor")) {
                // 更新指标监测值
                if (!updateOrSaveMonitorValue(idtIndicators, warnRule)) {
                    return new AjaxResult(StatusCode.ERROR_CODE_40005, "关联模型结果数据格式错误，请检查!");
                }
            } else if (idtIndicators.getDataType().equals("evaluate")) {
                // 更新指标评估值
                if (!updateOrSaveReportValue(idtIndicators, warnRule)) {
                    return new AjaxResult(StatusCode.ERROR_CODE_40005, "关联模型结果数据格式错误，请检查!");
                }
            } else {
                // 更新指标规划值
                if (!updateOrSaveTargetValue(idtIndicators)) {
                    return new AjaxResult(StatusCode.ERROR_CODE_40005, "关联模型结果数据格式错误，请检查!");
                }
            }

        }
        //默认给个值吧
        if (StringUtils.isBlank(idtIndicators.getDutyCompanyType())) {
            Map<String, String> dutyCompanyTypeMap = iRedisDictService.getItemMaps(IdtIndicatorsConst.DUTY_COMPANY_TYPE);
            for (Map.Entry<String, String> entry : dutyCompanyTypeMap.entrySet()) {
                idtIndicators.setDutyCompanyType(entry.getKey());
                break;
            }
        }
        idtIndicatorsService.save(idtIndicators);
        if (idtIndicators.getDatasource().equals("hand")) {
            // 手动录入的指标则更新状态
            idtIndicatorsService.updateStatus(idtIndicators.getId());
        }
        //自动新增对标配置
        IdtYearRelevance yearRelevance = new IdtYearRelevance();
        yearRelevance.setId(UuidUtil.get32UUID());
        yearRelevance.setIndicatorsId(idtIndicators.getId());
        yearRelevance.setMonitorReportYear("2000-2500");
        yearRelevance.setPlanTargetYear(2035);
        yearRelevance.setCreator(AuthUtil.getUserId().toString());
        yearRelevance.setCreateTime(new Date());
        iIdtYearRelevanceService.save(yearRelevance);
        return new AjaxResult();
    }

    /**
     * @描述: 修改
     * @入参:
     * @出参:
     * @作者: 彭辉
     * @日期: 2020-06-05
     **/
    @PostMapping("/update")
    @ApiOperation(value = "修改")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult update(IdtIndicators idtIndicators) {
        // 2021-12-10 陈宏成 判断是否指标重名
        boolean hasName = this.idtIndicatorsService.hasName(idtIndicators.getName(), idtIndicators.getId());
        if (hasName) {
            return new AjaxResult(StatusCode.ERROR_CODE_40005, "该指标名称已存在，请修改指标名称。");
        }
        // 20210804 新增指标预警规则字段
        if (StringUtils.isNotBlank(idtIndicators.getWarnRuleConfig())) {
            idtIndicators.setWarnRuleConfig(StringEscapeUtils.unescapeXml(idtIndicators.getWarnRuleConfig()));
        }
        // 20230424 新增评估规则配置字段
        if (StringUtils.isNotBlank(idtIndicators.getEstimateRuleConfig())) {
            idtIndicators.setEstimateRuleConfig(StringEscapeUtils.unescapeXml(idtIndicators.getEstimateRuleConfig()));
        }
        //String dbWarnRuleId = idtIndicatorsService.getById(idtIndicators.getId()).getWarnRuleId();
        prepareData(idtIndicators, false);
        //如果数据来源于模型结果，则遍历更新该指标对应监测值
        //获取预警规则
        IdtWarnRule warnRule = iIdtWarnRuleService.getById(idtIndicators.getWarnRuleId());
        if (warnRule == null) {
            return new AjaxResult(StatusCode.ERROR_CODE_40005, "该指标对预警规则为空!");
        }
        if (idtIndicators.getDatasource().equals("model")) {
            // 根据数据类型选择更新的指标数值
            if (idtIndicators.getDataType().equals("monitor")) {
                // 更新指标监测值
                if (!updateOrSaveMonitorValue(idtIndicators, warnRule)) {
                    return new AjaxResult(StatusCode.ERROR_CODE_40005, "关联模型结果数据格式错误，请检查!");
                }
            } else if (idtIndicators.getDataType().equals("evaluate")) {
                // 更新指标评估值
                if (!updateOrSaveReportValue(idtIndicators, warnRule)) {
                    return new AjaxResult(StatusCode.ERROR_CODE_40005, "关联模型结果数据格式错误，请检查!");
                }
            } else {
                // 更新指标规划值
                if (!updateOrSaveTargetValue(idtIndicators)) {
                    return new AjaxResult(StatusCode.ERROR_CODE_40005, "关联模型结果数据格式错误，请检查!");
                }
            }
        }
        //当前指标项更新
        idtIndicatorsService.updateById(idtIndicators);
        // 当预警规则发生变化时，更新预警状态，达标状态
        // if (!dbWarnRuleId.equals(idtIndicators.getWarnRuleId())) {
        idtReportValueService.updateWarnStatusAndStandard(idtIndicators.getId(), warnRule);
        //}
        return new AjaxResult();
    }


    private IMapClient iMapClient;

    @Resource
    public void setIMapClient(IMapClient iMapClient) {
        this.iMapClient = iMapClient;
    }

    /**
     * @描述: 指标更新、保存操作时保存指标监测值
     * @入参:
     * @出参:
     * @作者: 代鹏刚
     * @日期: 2020/8/6 10:00
     **/
    public Boolean updateOrSaveMonitorValue(IdtIndicators idtIndicators, IdtWarnRule warnRule) {
        Boolean flag = true;
        // 存放需新增的指标监测值集合
        List<IdtMonitorValue> idtMonitorValueAdds = new ArrayList<>();
        // 存放需更新的指标监测值集合
        List<IdtMonitorValue> idtMonitorValueUpdates = new ArrayList<>();
        // 模型解析出来的
        List<IdtMonitorValue> idtMonitorValues = new ArrayList<>();

        // 获取该指标关联的模型结果数据集合
        LambdaQueryWrapper<MdlModelResult> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.like(MdlModelResult::getModelIds, idtIndicators.getModelId());
        List<MdlModelResult> mdlModelResults = iMdlModelResultService.list(lambdaQueryWrapper);
        // 遍历模型结果数据集，拿到各个年份的模型结果数据
        List<Map<String, String>> resultMap = idtIndicatorsService.analysisModelResult(mdlModelResults, idtIndicators);
        if (CollectionUtils.isEmpty(resultMap)) {
            return false;
        }

        // 查询全部行政区划
        Map<String, String> mapAllDivision = this.iMapClient.mapAllDivision();
        // 重模型中构建监测值
        for (Map<String, String> map : resultMap) {
            IdtMonitorValue monitorValues = new IdtMonitorValue();
            monitorValues.setId(UuidUtil.get32UUID());
            // 处理行政区划编码
            String dCode = map.get("dCode");
            String divisionTrimZero = CommonUtil.divisionTrimZero(dCode);
            // 如果系统中有去0的区划代码，就直接用去0的，否则就用原来的
            if (Objects.nonNull(mapAllDivision) && mapAllDivision.containsKey(divisionTrimZero)) {
                monitorValues.setDivisionCode(divisionTrimZero);
            } else {
                monitorValues.setDivisionCode(dCode);
            }
            monitorValues.setMonitorValue(map.get("mValue"));
            monitorValues.setYear(Integer.parseInt(map.get("year")));
            monitorValues.setCreateTime(new Date());
            monitorValues.setCreator(this.getUser().getUserId().toString());
            monitorValues.setOrgId(this.getUser().getDeptId());
            monitorValues.setIndicatorsId(idtIndicators.getId());
            monitorValues.setWarnStatus("正常");
            if (Objects.equals(idtIndicators.getUpdateCycle(), "year")) {
                monitorValues.setMonitorTime(map.get("year"));
            } else if (Objects.equals(idtIndicators.getUpdateCycle(), "quarter")) {
                monitorValues.setMonitorTime(map.get("year") + "-4");
            } else if (Objects.equals(idtIndicators.getUpdateCycle(), "month")) {
                monitorValues.setMonitorTime(map.get("year") + "-12");
            } else {
                throw new BaseRuntimeException("更新周期只能是年度、月度、季度！");
            }
            idtMonitorValues.add(monitorValues);
        }
        if (CollectionUtils.isEmpty(idtMonitorValues)) {
            return false;
        }

        //判断指标监测值集合那些是需要更新那些是需要新增
        LambdaQueryWrapper<IdtMonitorValue> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(IdtMonitorValue::getIndicatorsId, idtIndicators.getId());
        List<IdtMonitorValue> idtMonitorValuesInDb = this.iIdtMonitorValueService.list(queryWrapper);
        //计算需要更新的指标监测值集合
        idtMonitorValues.stream().forEach(mvFromModel -> {
            Optional<IdtMonitorValue> monitorValueOptional = idtMonitorValuesInDb.stream().filter(mvFromDB ->
                    Objects.equals(mvFromModel.getYear(), mvFromDB.getYear())
                            && Objects.equals(mvFromModel.getIndicatorsId(), mvFromDB.getIndicatorsId())
                            && Objects.equals(mvFromModel.getDivisionCode(), mvFromDB.getDivisionCode())
                            && Objects.equals(mvFromModel.getMonitorTime(), mvFromDB.getMonitorTime())).findFirst();
            if (monitorValueOptional.isPresent()) {
                // 存在，更新
                IdtMonitorValue mvFromDB = monitorValueOptional.get();
                mvFromDB.setMonitorValue(mvFromModel.getMonitorValue());
                mvFromDB.setModifyTime(new Date());
                LoginUser user = AuthUtil.getUser();
                mvFromDB.setModifier(Objects.isNull(user) ? null : user.getUserId().toString());
                idtMonitorValueUpdates.add(mvFromDB);
            } else {
                // 不存在，新增
                idtMonitorValueAdds.add(mvFromModel);
            }
        });
        //指标监测值数据库操作
        if (!CollectionUtils.isEmpty(idtMonitorValueAdds)) {
            //新增操作
            this.iIdtMonitorValueService.saveBatch(idtMonitorValueAdds);
        }
        if (!CollectionUtils.isEmpty(idtMonitorValueUpdates)) {
            //更新操作
            iIdtMonitorValueService.updateBatchById(idtMonitorValueUpdates);
        }
        return flag;
    }

    /**
     * @描述: 指标更新、保存操作时保存指标上报值
     * @入参:
     * @出参:
     * @作者: 代鹏刚
     * @日期: 2021/7/6 16:35
     **/
    public Boolean updateOrSaveReportValue(IdtIndicators idtIndicators, IdtWarnRule warnRule) {
        Boolean flag = true;
        // 存放需新增的指标上报值集合
        List<IdtReportValue> idtReportValueAdds = new ArrayList<>();
        // 存放需更新的指标上报值集合
        List<IdtReportValue> idtReportValueUpdates = new ArrayList<>();
        // 获取该指标关联的模型结果数据集合
        LambdaQueryWrapper<MdlModelResult> lambdaQueryWrapper = (new QueryWrapper()).lambda();
        lambdaQueryWrapper.like(MdlModelResult::getModelIds, idtIndicators.getModelId());
        List<MdlModelResult> mdlModelResults = iMdlModelResultService.list(lambdaQueryWrapper);
        // 遍历模型结果数据集，拿到各个年份的模型结果数据
        List<Map<String, String>> resultMap = idtIndicatorsService.analysisModelResult(mdlModelResults, idtIndicators);
        if (resultMap.size() == 0) {
            return false;
        }
        for (Map<String, String> map : resultMap) {
            IdtReportValue idtReportValue = new IdtReportValue();
            idtReportValue.setId(UuidUtil.get32UUID());
            idtReportValue.setDivisionCode(map.get("dCode"));
            idtReportValue.setValue(map.get("mValue"));
            idtReportValue.setYear(Integer.parseInt(map.get("year")));
            idtReportValue.setCreateTime(new Date());
            idtReportValue.setCreator(this.getUser().getUserId().toString());
            idtReportValue.setOrgId(this.getUser().getDeptId());
            idtReportValue.setIndicatorsId(idtIndicators.getId());
            idtReportValue.setWarnStatus("正常");
            // 计算统一率、达标状态
            //判断是否统一
            Integer unify = idtReportValueService.isUnify(idtReportValue.getIndicatorsId(), idtReportValue.getYear() + "", idtReportValue.getDivisionCode(), idtReportValue.getValue());
            idtReportValue.setIsUnify(unify);
            //判断是否达标
            Integer standard = idtReportValueService.isStandard(idtReportValue.getIndicatorsId(), idtReportValue.getYear() + "", idtReportValue.getDivisionCode(), idtReportValue.getValue());
            idtReportValue.setIsStandard(standard);
            idtReportValueAdds.add(idtReportValue);
        }
        //根据指标ID查询指标规划值
        Map map = new HashMap();
        map.put("indicators_id", idtIndicators.getId());
        List<IdtTargetValue> idtTargetValues = (List<IdtTargetValue>) iIdtTargetValueService.listByMap(map);
        List<IdtReportValue> idtReportValueNewAdds = new ArrayList<>();
        if (idtTargetValues != null && idtTargetValues.size() > 0) {
            //更新预警状态
            idtReportValueNewAdds = idtReportValueAdds.stream().map(x -> {
                Optional<IdtTargetValue> idtTargetValue = idtTargetValues.stream().filter(y -> x.getDivisionCode().equals(y.getDivisionCode())).findFirst();
                if (idtTargetValue.isPresent()) {
                    if ("正向".equals(warnRule.getName())) {
                        if (Float.parseFloat(x.getValue()) > Float.parseFloat(idtTargetValue.get().getTargetValue())) {
                            x.setWarnStatus("正常");
                        } else {
                            x.setWarnStatus("预警");
                        }
                    } else if ("反向".equals(warnRule.getName())) {
                        if (Float.parseFloat(x.getValue()) < Float.parseFloat(idtTargetValue.get().getTargetValue())) {
                            x.setWarnStatus("正常");
                        } else {
                            x.setWarnStatus("预警");
                        }
                    }
                }
                return x;
            }).collect(Collectors.toList());
        } else {
            //当前指标没有规划值
            idtReportValueNewAdds = idtReportValueAdds;
        }
        //判断指标上报值集合那些是需要更新那些是需要新增
        Map newMap = new HashMap();
        newMap.put("indicators_id", idtIndicators.getId());
        List<IdtReportValue> idtReportValues = (List<IdtReportValue>) idtReportValueService.listByMap(newMap);
        //计算需要更新的指标监测值集合
        List<IdtReportValue> idtReportValueListUpdate = new ArrayList<>();
        if (idtReportValues != null && idtReportValues.size() > 0) {
            idtReportValueNewAdds.stream().map(x -> {
                Optional<IdtReportValue> idtReportValue = idtReportValues.stream().filter(y -> x.getYear().equals(y.getYear()) && x.getDivisionCode().equals(y.getDivisionCode())).findFirst();
                if (idtReportValue.isPresent()) {
                    idtReportValueUpdates.add(x);
                    x.setId(idtReportValue.get().getId());
                    idtReportValueListUpdate.add(x);
                }
                return x;
            }).collect(Collectors.toList());
        }
        //计算需要新增的指标监测值集合
        if (idtReportValueUpdates.size() > 0) {
            idtReportValueNewAdds.removeAll(idtReportValueUpdates);
        }
        //指标监测值数据库操作
        if (idtReportValueNewAdds.size() > 0) {
            //新增操作
            idtReportValueService.saveBatch(idtReportValueNewAdds);
        }
        if (idtReportValueListUpdate.size() > 0) {
            //更新操作
            List<IdtReportValue> idtReportValueArrayList = new ArrayList<>();
            for (IdtReportValue idtReportValue : idtReportValueListUpdate) {
                IdtReportValue reportValue = new IdtReportValue();
                reportValue.setId(idtReportValue.getId());
                reportValue.setValue(idtReportValue.getValue());
                reportValue.setWarnStatus(idtReportValue.getWarnStatus());
                reportValue.setOrgId(idtReportValue.getOrgId());
                reportValue.setIndicatorsId(idtReportValue.getIndicatorsId());
                reportValue.setModifier(this.getUser().getUserId().toString());
                reportValue.setModifyTime(new Date());
                idtReportValueArrayList.add(reportValue);
            }
            idtReportValueService.updateBatchById(idtReportValueArrayList);
        }
        // 更新指标表中的更新状态
        iIdtIndicatorsService.updateReportStatus(idtIndicators.getId());
        return flag;
    }

    /**
     * @描述: 指标更新、保存操作时保存指标规划值
     * @入参:
     * @出参:
     * @作者: 代鹏刚
     * @日期: 2021/7/6 16:35
     **/
    public Boolean updateOrSaveTargetValue(IdtIndicators idtIndicators) {
        Boolean flag = true;
        // 存放需新增的指标监测值集合
        List<IdtTargetValue> idtTargetValueAdds = new ArrayList<>();
        // 存放需更新的指标监测值集合
        List<IdtTargetValue> idtTargetValueUpdates = new ArrayList<>();
        // 获取该指标关联的模型结果数据集合
        LambdaQueryWrapper<MdlModelResult> lambdaQueryWrapper = (new QueryWrapper()).lambda();
        lambdaQueryWrapper.like(MdlModelResult::getModelIds, idtIndicators.getModelId());
        List<MdlModelResult> mdlModelResults = iMdlModelResultService.list(lambdaQueryWrapper);
        // 遍历模型结果数据集，拿到各个年份的模型结果数据
        List<Map<String, String>> resultMap = idtIndicatorsService.analysisModelResult(mdlModelResults, idtIndicators);
        if (resultMap.size() == 0) {
            return false;
        }
        for (Map<String, String> map : resultMap) {
            IdtTargetValue targetValues = new IdtTargetValue();
            targetValues.setId(UuidUtil.get32UUID());
            targetValues.setBaseValue(idtIndicators.getBaseValue());
            targetValues.setBaseYear(idtIndicators.getBaseYear());
            targetValues.setDivisionCode(map.get("dCode"));
            targetValues.setTargetValue(map.get("mValue"));
            targetValues.setTargetYear(Integer.parseInt(map.get("year")));
            targetValues.setCreateTime(new Date());
            targetValues.setCreator(this.getUser().getUserId().toString());
            targetValues.setOrgId(this.getUser().getDeptId());
            targetValues.setIndicatorsId(idtIndicators.getId());
            //修改规划值时，同步更新监测值的预警字段以及上报值的达标率
            iIdtMonitorValueService.updateWarnStatus(targetValues.getIndicatorsId(), targetValues.getDivisionCode(), targetValues.getTargetYear() + "", targetValues.getTargetValue());
            idtReportValueService.updateStandard(targetValues.getIndicatorsId(), targetValues.getDivisionCode(), targetValues.getTargetYear() + "", targetValues.getTargetValue());
            idtTargetValueAdds.add(targetValues);
        }
        List<IdtTargetValue> idtTargetValueNewAdds = new ArrayList<>();
        idtTargetValueNewAdds = idtTargetValueAdds;
        //判断指标监测值集合那些是需要更新那些是需要新增
        Map newMap = new HashMap();
        newMap.put("indicators_id", idtIndicators.getId());
        List<IdtTargetValue> idtTargetValues = (List<IdtTargetValue>) iIdtTargetValueService.listByMap(newMap);
        //计算需要更新的指标监测值集合
        List<IdtTargetValue> idtTargetValueListUpdate = new ArrayList<>();
        if (idtTargetValues != null && idtTargetValues.size() > 0) {
            idtTargetValueNewAdds.stream().map(x -> {
                Optional<IdtTargetValue> idtTargetValue = idtTargetValues.stream().filter(y -> x.getTargetYear().equals(y.getTargetYear()) && x.getDivisionCode().equals(y.getDivisionCode())).findFirst();
                if (idtTargetValue.isPresent()) {
                    idtTargetValueUpdates.add(x);
                    x.setId(idtTargetValue.get().getId());
                    idtTargetValueListUpdate.add(x);
                }
                return x;
            }).collect(Collectors.toList());
        }
        //计算需要新增的指标监测值集合
        if (idtTargetValueUpdates.size() > 0) {
            idtTargetValueNewAdds.removeAll(idtTargetValueUpdates);
        }
        //指标监测值数据库操作
        if (idtTargetValueNewAdds.size() > 0) {
            //新增操作
            iIdtTargetValueService.saveBatch(idtTargetValueNewAdds);
        }
        if (idtTargetValueListUpdate.size() > 0) {
            //更新操作
            List<IdtTargetValue> idtTargetValueArrayList = new ArrayList<>();
            for (IdtTargetValue idtTargetValue : idtTargetValueListUpdate) {
                IdtTargetValue targetValue = new IdtTargetValue();
                targetValue.setId(idtTargetValue.getId());
                targetValue.setTargetValue(idtTargetValue.getTargetValue());
                targetValue.setOrgId(idtTargetValue.getOrgId());
                targetValue.setBaseYear(idtTargetValue.getBaseYear());
                targetValue.setBaseValue(idtTargetValue.getBaseValue());
                targetValue.setModifier(this.getUser().getUserId().toString());
                targetValue.setModifyTime(new Date());
                targetValue.setIndicatorsId(idtTargetValue.getIndicatorsId());
                idtTargetValueArrayList.add(targetValue);
            }
            iIdtTargetValueService.updateBatchById(idtTargetValueArrayList);
        }
        return flag;
    }

    /**
     * @描述: 根据主键删除
     * @入参: id
     * @出参:
     * @作者: 彭辉
     * @日期: 2020-06-05
     **/
    @PostMapping("/delete")
    @ApiOperation(value = "根据主键删除")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "ID", required = true,
                    dataType = "string", paramType = "query")
    })
    public AjaxResult delete(String id) {
        List<String> ids = Arrays.asList(id.split(","));
        this.idtIndicatorsService.deleteIndicatorByIds(ids);
        return new AjaxResult();
    }

    /**
     * @描述：导出指标Excel
     * @作者：彭辉
     * @时间：2020/6/9 10:39
     */
    @PostMapping("/exportExcel")
    @ApiOperation(value = "导出指标Excel")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "exportType", value = "导出类型", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "datasource", value = "数据来源(指标填报传:hand)", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "ids", value = "导出指标id集合", required = false, dataType = "string", paramType = "query")
    })
    public void exportExcel(String exportType, String datasource, String ids) {
        List<IdtIndicators> list = null;
        if ("all".equals(exportType)) {
            QueryWrapper<IdtIndicators> wrapper = new QueryWrapper();
            this.queryConditions(wrapper, null);
            wrapper.orderByAsc("code");
            // 导出所有指标
            list = idtIndicatorsService.list(wrapper);
        } else {
            // 导出选中指标
            list = (List<IdtIndicators>) idtIndicatorsService.listByIds(Arrays.asList(ids.split(",")));
        }
        // 匹配行政区划名称时，不走字典的redis缓存取值，查询map_division(行政区划表)获取对应的行政区划名称
        PageData pageData = new PageData();
        List<PageData> divisionList = idtIndicatorsService.listDivisionByEntity(pageData);
        Map<String, String> dictMap = new HashMap<>();
        for (PageData data : divisionList) {
            dictMap.put(data.get("code").toString(), data.get("name").toString());
        }
        List<Object[]> dataList = new ArrayList<Object[]>();

        Map<String, String> typeMap = iRedisDictService.getItemMaps(IdtIndicatorsConst.DICT_INDICATORS_TYPE);
        Map<String, String> attributeMap = iRedisDictService.getItemMaps(IdtIndicatorsConst.DICT_INDICATORS_ATTRIBUTE);
        Map<String, String> scopeMap = iRedisDictService.getItemMaps(IdtIndicatorsConst.DICT_INDICATORS_SCOPE);
        Map<String, String> updateCycleMap = iRedisDictService.getItemMaps(IdtIndicatorsConst.DICT_UPDATE_CYCLE);
        Map<String, String> datasourceMap = iRedisDictService.getItemMaps(IdtIndicatorsConst.DICT_DATASOURCE);

        Map<String, String> deptMap = iIdtIndicatorsService.getDeptNameMap();

        for (int i = 0; i < list.size(); i++) {
            IdtIndicators indicators = list.get(i);
            Object[] datas = new Object[16];
            datas[0] = indicators.getCode();
            datas[1] = indicators.getName();
            datas[2] = typeMap.get(indicators.getType());
            datas[3] = indicators.getUnit();
            datas[4] = attributeMap.get(indicators.getAttribute());
            datas[5] = scopeMap.get(indicators.getScope());
            datas[6] = indicators.getConnotation();
            // String divisionCode = indicators.getDivisionCode().indexOf("00") == -1 ? indicators.getDivisionCode() : indicators.getDivisionCode().substring(0, indicators.getDivisionCode().indexOf("00"));
            // datas[7] = iRedisDictService.getText(IdtIndicatorsConst.DICT_QYDM, divisionCode);
            ///// datas[7] = dictMap.get(indicators.getDivisionCode());
            ///// datas[8] = indicators.getDivisionCode();
            ///// datas[9] = iRedisDictService.getText(IdtIndicatorsConst.DICT_IS_PUBLIC_INDICATORS, indicators.getIsPublic() + "");

            datas[7] = iIdtIndicatorsService.getDeptNameStr(indicators.getDutyCompany(), deptMap);
            datas[8] = iIdtIndicatorsService.getDeptNameStr(indicators.getDutyDepartment(), deptMap);
            datas[9] = updateCycleMap.get(indicators.getUpdateCycle());
            // datas[10] = iRedisDictService.getText(IdtIndicatorsConst.DICT_IMPORTANT_DEGREE, indicators.getImportantLevel());
            datas[10] = datasourceMap.get(indicators.getDatasource());
            ;
            datas[11] = indicators.getCalculateSource();
            dataList.add(datas);
        }
        // 导出Excel
        // String[] titles = {"指标编号", "指标名称", "指标类型", "指标单位", "指标属性", "指标范围", "指标内涵", "行政区划名称", "行政区划代码", "是否为公共指标", "采集单位", "责任单位", "更新周期", "重要程度", "数据来源", "指标计算及来源说明"};
        String[] titles = {"指标编号", "指标名称", "指标类型", "指标单位", "指标属性", "指标范围", "指标内涵", "责任单位", "责任处室", "更新周期", "数据来源", "指标计算及来源说明"};
        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
        response.setHeader("Content-type", "text/html;charset=UTF-8");
        response.setCharacterEncoding("UTF-8");
        ExcelUtil.exportExcel(response, "指标项", "指标项信息", titles, dataList);
    }

    /**
     * @描述：判断Excel导入指标是否存在
     * @作者：彭辉
     * @时间：2020/6/10 8:55
     */
    @PostMapping("/isExistsExcel")
    @ApiOperation(value = "判断Excel导入指标是否存在")
    public AjaxResult isExistsExcel(MultipartHttpServletRequest multipartRequest) {
        MultipartFile multipartFile = multipartRequest.getFile("file");
        if (multipartFile.isEmpty()) {
            new AjaxResult(StatusCode.ERROR_CODE_40005, "导入文件不能为空！");
        }
        // 根据上传MultipartFile对象获取excel数据集
        List<List<String>> excelList = ExcelUtil.getExcelData(multipartFile);
        if (excelList == null && excelList.size() <= 1) {
            new AjaxResult(StatusCode.ERROR_CODE_40005, "导入文件数据为空！");
        }
        String resultName = "";
        //  2021-12-09 判断指标名是否重名
        // 获取所有指标集合
        LambdaQueryWrapper<IdtIndicators> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(IdtIndicators::getName);
        List<IdtIndicators> allList = idtIndicatorsService.list(queryWrapper);
        // 重名判断
        Set<String> idtNameList = allList.stream().map(IdtIndicators::getName).collect(Collectors.toSet());
        // 排除第一个元素
        excelList.remove(0);
        // 获取Excel中的名字列表
        Set<String> excelNameList = excelList.stream().map(list -> {
            return list.get(0);
        }).collect(Collectors.toSet());
        excelNameList.retainAll(idtNameList);
        // 整理重名的结果
        if (!excelNameList.isEmpty()) {
            resultName = String.join(",", excelNameList);
        }
        return new AjaxResult(resultName);
    }

    /**
     * @描述：导入指标Excel
     * @作者：彭辉
     * @时间：2020/6/9 20:47
     */
    @PostMapping("/importExcel")
    @ApiOperation(value = "导入指标Excel")
    @ApiImplicitParam(name = "isUpdate", value = "是否更新", required = true, dataType = "string", paramType = "query")
    public AjaxResult importExcel(MultipartHttpServletRequest multipartRequest, String isUpdate) {
        MultipartFile multipartFile = multipartRequest.getFile("file");
        if (multipartFile.isEmpty()) {
            new AjaxResult(StatusCode.ERROR_CODE_40005, "导入文件不能为空！");
        }
        // 根据上传MultipartFile对象获取excel数据集
        List<List<String>> excelList = ExcelUtil.getExcelData(multipartFile);
        if (excelList == null && excelList.size() <= 1) {
            new AjaxResult(StatusCode.ERROR_CODE_40005, "导入文件数据为空！");
        }
        // 根据数据字典key获取信息
        Map<String, String> typeList = iRedisDictService.getItemNameMaps(IdtIndicatorsConst.DICT_INDICATORS_TYPE);
        Map<String, String> updateCycleList = iRedisDictService.getItemNameMaps(IdtIndicatorsConst.DICT_UPDATE_CYCLE);
        Map<String, String> attributeList = iRedisDictService.getItemNameMaps(IdtIndicatorsConst.DICT_INDICATORS_ATTRIBUTE);
        Map<String, String> scopeList = iRedisDictService.getItemNameMaps(IdtIndicatorsConst.DICT_INDICATORS_SCOPE);

        Map<String, IdtWarnRule> warnRuleMap = iIdtWarnRuleService.getWarnRuleMap();

        // 获取所有指标集合
        List<IdtIndicators> allList = idtIndicatorsService.list();
        // 记录所有指标编号
        // 存储指标编号对应指标id，用于后续判断是否存在同名指标，key -- 指标名， value -- 指标
        Map<String, IdtIndicators> idtMap = allList.stream().collect(Collectors.toMap(IdtIndicators::getName, idt -> idt));

        Map<String, String> deptMap = iIdtIndicatorsService.getDeptIdMap();

        // 获取当前年份
        String year = DateUtil.getYear();
        Integer codeNum = null;

        // 指标编号
        LambdaQueryWrapper<IdtIndicators> lambda = new QueryWrapper().lambda();
        lambda.like(IdtIndicators::getCode, year);
        lambda.orderByDesc(IdtIndicators::getCode);
        List<IdtIndicators> list = idtIndicatorsService.list(lambda);
        if (list != null && list.size() > 0) {
            String num = list.get(0).getCode().replace(year, "");
            codeNum = Integer.valueOf(num) + 1;
        } else {
            codeNum = 1;
        }
        // 存储新增、更新指标集合
        List<IdtIndicators> saveUpdateList = new ArrayList<IdtIndicators>();
        for (int i = 1; i < excelList.size(); i++) {
            String code = year + String.format("%03d", codeNum);
            List<String> dataList = excelList.get(i);
            IdtIndicators indicators = new IdtIndicators();

            indicators.setId(UuidUtil.get32UUID());
            this.prepareData(indicators, true);

            if (StringUtils.isBlank(dataList.get(0))) {
                return new AjaxResult(StatusCode.ERROR_CODE_40005, "指标名称不能为空！");
            }
            if (StringUtils.isBlank(dataList.get(1))) {
                return new AjaxResult(StatusCode.ERROR_CODE_40005, "指标类型不能为空！");
            }
            //if(StringUtils.isBlank(dataList.get(2))){
            //    return new AjaxResult(StatusCode.ERROR_CODE_40005, "指标单位不能为空！");
            //}
            if (StringUtils.isBlank(dataList.get(3))) {
                return new AjaxResult(StatusCode.ERROR_CODE_40005, "指标属性不能为空！");
            }
            if (StringUtils.isBlank(dataList.get(4))) {
                return new AjaxResult(StatusCode.ERROR_CODE_40005, "指标范围不能为空！");
            }
            if (StringUtils.isBlank(dataList.get(6))) {
                return new AjaxResult(StatusCode.ERROR_CODE_40005, "责任单位不能为空！");
            }
            if (StringUtils.isBlank(dataList.get(7))) {
                return new AjaxResult(StatusCode.ERROR_CODE_40005, "责任处室不能为空！");
            }
            if (StringUtils.isBlank(dataList.get(8))) {
                return new AjaxResult(StatusCode.ERROR_CODE_40005, "更新周期不能为空！");
            }
            if (StringUtils.isBlank(dataList.get(9))) {
                return new AjaxResult(StatusCode.ERROR_CODE_40005, "预警规则不能为空！");
            }
            // 过滤掉excel中重复的指标
            boolean present = saveUpdateList.stream().filter(idt -> {
                return idt.getName().equals(dataList.get(0));
            }).findAny().isPresent();
            if (present == true) {
                continue;
            }
            //  2021-12-09 判断指标名是否重名
            // 判断指标是否已经存在
            if (idtMap.containsKey(dataList.get(0))) {
                if (StringUtils.isNotBlank(isUpdate) && Objects.equals(isUpdate, "true")) {
                    // 指定为更新模式，更新
                    indicators = idtMap.get(dataList.get(0));
                    this.prepareData(indicators, false);
                    code = indicators.getCode();
                } else {
                    // 否则，跳过
                    continue;
                }
            }
            // 赋值编码流水
            indicators.setCode(code);
            indicators.setName(dataList.get(0));
            indicators.setType(typeList.get(dataList.get(1)));
            indicators.setUnit(dataList.get(2));

            indicators.setAttribute(attributeList.get(dataList.get(3)));
            indicators.setScope(scopeList.get(dataList.get(4)));
            indicators.setConnotation(dataList.get(5));

            String dutyCompany = idtIndicatorsService.getDeptNameStr(dataList.get(6), deptMap);
            if (StringUtils.isBlank(dutyCompany)) {
                return new AjaxResult(StatusCode.ERROR_CODE_40005, "责任单位：'" + dataList.get(6) + "'无法匹配到平台机构单位！");
            }
            indicators.setDutyCompany(dutyCompany);

            String dutyDepartment = idtIndicatorsService.getDeptNameStr(dataList.get(7), deptMap);
            if (StringUtils.isBlank(dutyDepartment)) {
                return new AjaxResult(StatusCode.ERROR_CODE_40005, "责任处室：'" + dataList.get(7) + "'无法匹配到平台机构单位！");
            }
            indicators.setDutyDepartment(dutyDepartment);

            indicators.setUpdateCycle(updateCycleList.get(dataList.get(8)));
            indicators.setWarnRuleId(warnRuleMap.get(dataList.get(9)).getId());
            indicators.setCalculateSource(dataList.get(10));

            // 默认更新方式、数据来源（手动更新）
            indicators.setUpdateType(1);
            indicators.setDatasource("hand");

            indicators.setSortStatus(0);
            //给个默认值吧
            if (StringUtils.isBlank(indicators.getDutyCompanyType())) {
                Map<String, String> dutyCompanyTypeMap = iRedisDictService.getItemMaps(IdtIndicatorsConst.DUTY_COMPANY_TYPE);
                for (Map.Entry<String, String> entry : dutyCompanyTypeMap.entrySet()) {
                    indicators.setDutyCompanyType(entry.getKey());
                    break;
                }
            }
            saveUpdateList.add(indicators);
            codeNum++;
        }
        if (saveUpdateList.size() > 0) {
            // 批量保存更新
            idtIndicatorsService.saveOrUpdateBatch(saveUpdateList);
        }
        return new AjaxResult();
    }

    /**
     * @描述:列出查询的字典项
     * @入参:
     * @出参:
     * @作者: 戴伙进
     * @日期: 2020/6/11 11:44
     **/
    @PostMapping("/listByDirId")
    @ApiOperation(value = "查询不在该指标目录下不关联的所有指标信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "current", value = "当前页码", required = true, dataType = "long", paramType = "query", example = "1"),
            @ApiImplicitParam(name = "size", value = "每页显示数量", required = true, dataType = "long", paramType = "query", example = "10"),
            @ApiImplicitParam(name = "dirId", value = "指标目录id", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "name", value = "关键字搜索", dataType = "string", paramType = "query"),
    })
    public AjaxResult listByDirId(@ApiIgnore Page page, @ApiIgnore IdtIndicators idtIndicators, String dirId) {
        if (StringUtils.isBlank(dirId)) {
            return new AjaxResult(StatusCode.ERROR_CODE_40005, "指标目录dirId不能为空");
        }
        QueryWrapper<IdtIndicators> wrapper = new QueryWrapper();
        wrapper.notInSql("id", "select indicators_id from idt_indicators_dir where parent_id = '" + dirId + "'");
        // 设置分页查询条件
        this.queryConditions(wrapper, idtIndicators);
        IPage<IdtIndicators> iPage = idtIndicatorsService.page(page, wrapper);
        return new AjaxResult(iPage);
    }

    /**
     * @描述:累出所有的数据
     * @入参:
     * @出参:
     * @作者: 戴伙进
     * @日期: 2020/6/15 17:14
     **/
    @PostMapping("/listAllList")
    @ApiOperation(value = "查询表中所有的记录")
    public AjaxResult listAllList() {
        LambdaQueryWrapper<IdtIndicators> queryWrapper = (new QueryWrapper()).lambda();
        // 查询公共的或本单位的
        ////// queryWrapper.eq(IdtIndicators::getIsPublic,1).or().eq(IdtIndicators::getOrgId, this.getUser().getDeptId());

        queryWrapper.orderByAsc(IdtIndicators::getCode);
        List<IdtIndicators> list = idtIndicatorsService.list(queryWrapper);
        return new AjaxResult(list);
    }


    // 根据数据字典文本获取编码
    private String getDictCodeByText(List<Map<String, String>> dictList, String text) {
        String code = null;
        if ((dictList == null && dictList.size() == 0) || StringUtils.isBlank(text)) {
            return code;
        }
        for (Map<String, String> map : dictList) {
            if (map.get("text").equals(text)) {
                code = map.get("code");
                break;
            }
        }
        return code;
    }

    /**
     * @描述：赋值创建人、创建时间、修改人、修改时间字段值
     * @作者：彭辉
     * @时间：2020/6/9 10:39
     */
    private void prepareData(IdtIndicators idtIndicators, boolean isSave) {
        if (isSave) {
            idtIndicators.setCreator(this.getUser().getUserId().toString());
            idtIndicators.setCreateTime(new Date());
            // 防止误修改
            idtIndicators.setModifier(null);
            idtIndicators.setModifyTime(null);
        } else {
            idtIndicators.setModifier(this.getUser().getUserId().toString());
            idtIndicators.setModifyTime(new Date());
            // 防止误修改
            idtIndicators.setCreator(null);
            idtIndicators.setCreateTime(null);
        }
    }

    /**
     * @描述：分页查询省市县指标查询条件
     * @作者：彭辉
     * @时间：2020/6/6 10:04
     */
    private void queryConditions(QueryWrapper<IdtIndicators> wrapper, IdtIndicators idtIndicators) {
        // 根据当前用户获取所属单位信息
        // 查询市级公共指标、地方指标
        /*if (idtIndicators == null || idtIndicators.getIsPublic() == null) {
            // 市/县
            wrapper.and(i -> i.in("is_public", 1).or().eq("org_id", this.getUser().getDeptId()));
        } else if (idtIndicators.getIsPublic() == 0) {
            // 查询地方指标
            wrapper.eq("org_id", this.getUser().getDeptId()).eq("is_public", 0);
        } else if (idtIndicators.getIsPublic() == 1) {
            // 查询公共指标
            wrapper.eq("is_public", 1);
        }*/

        if (idtIndicators != null) {
            // 根据指标项名称模糊查询
            if (StringUtils.isNotBlank(idtIndicators.getName())) {
                wrapper.and(i -> i.like("name", idtIndicators.getName()).or().like("code", idtIndicators.getName()));
            }
            // 指标填报检索条件
            if (StringUtils.isNotBlank(idtIndicators.getDatasource())) {
                wrapper.eq("datasource", idtIndicators.getDatasource());
            }
            wrapper.apply("1 = 1");
            // 设置排序字段
            if ("desc".equals(idtIndicators.getSortWay())) {
                if (null != idtIndicators.getSortStatus() && idtIndicators.getSortStatus() == 1) {
                    wrapper.last(" ORDER BY (case when sort_status = 1 then 0 end) asc , (case when modifier = '" + this.getUser().getUserId().toString() + "' then 0 end) asc, " +
                            (StringUtils.isBlank(idtIndicators.getSort()) ? "code" : idtIndicators.getSort()) + " desc" + ",id desc");
                } else {
                    wrapper.orderByDesc(StringUtils.isBlank(idtIndicators.getSort()) ? "code" : idtIndicators.getSort());
                    wrapper.orderByDesc("id");
                }
            } else {
                // 设置默认排序
                if (null != idtIndicators.getSortStatus() && idtIndicators.getSortStatus() == 1) {
                    wrapper.last(" ORDER BY (case when sort_status = 1 then 0 end) asc , (case when modifier = '" + this.getUser().getUserId().toString() + "' then 0 end) asc, " +
                            (StringUtils.isBlank(idtIndicators.getSort()) ? "code" : idtIndicators.getSort()) + " asc" + ",id asc");
                } else {
                    wrapper.orderByAsc(StringUtils.isBlank(idtIndicators.getSort()) ? "code" : idtIndicators.getSort());
                    wrapper.orderByAsc("id");
                }
            }
        }
        /*// 查询省级/市级公共指标、地方指标
        if (idtIndicators == null || idtIndicators.getIsPublic() == null) {
            // 根据当前用户所属不同行政区划设置不同查询条件
            if (StringUtils.isNotBlank(baseOrg.getDisLevel5())) {
                // 村委
                wrapper.and(i -> i.eq("division_code", baseOrg.getDisLevel5())
                        .or(j -> j.eq("division_code", baseOrg.getDisLevel4()).eq("is_public", 4))
                        .or(k -> k.eq("division_code", baseOrg.getDisLevel3()).eq("is_public", 3))
                        .or(g -> g.eq("division_code", baseOrg.getDisLevel2() + "00").eq("is_public", 2))
                        .or(h -> h.eq("division_code", baseOrg.getDisLevel1() + "0000").eq("is_public", 1)));
            } else if (StringUtils.isNotBlank(baseOrg.getDisLevel4())) {
                // 街镇
                wrapper.and(i -> i.eq("division_code", baseOrg.getDisLevel4())
                        .or(j -> j.eq("division_code", baseOrg.getDisLevel3()).eq("is_public", 3))
                        .or(k -> k.eq("division_code", baseOrg.getDisLevel2() + "00").eq("is_public", 2))
                        .or(g -> g.eq("division_code", baseOrg.getDisLevel1() + "0000").eq("is_public", 1)));
            } else if (StringUtils.isNotBlank(baseOrg.getDisLevel3())) {
                // 县
                wrapper.and(i -> i.eq("division_code", baseOrg.getDisLevel3())
                        .or(j -> j.eq("division_code", baseOrg.getDisLevel2() + "00").eq("is_public", 2))
                        .or(k -> k.eq("division_code", baseOrg.getDisLevel1() + "0000").eq("is_public", 1)));
            } else if (StringUtils.isNotBlank(baseOrg.getDisLevel2())) {
                // 市
                wrapper.and(i -> i.eq("division_code", baseOrg.getDisLevel2() + "00")
                        .or(j -> j.eq("division_code", baseOrg.getDisLevel1() + "0000").eq("is_public", 1)));
            } else if (StringUtils.isNotBlank(baseOrg.getDisLevel1())) {
                // 省
                wrapper.eq("division_code", baseOrg.getDisLevel1() + "0000");
            }
        } else if (idtIndicators.getIsPublic() == 0) {
            // 查询地方指标
            if (StringUtils.isNotBlank(baseOrg.getDisLevel5())) {
                wrapper.eq("division_code", baseOrg.getDisLevel5()).eq("is_public", 0);
            } else if (StringUtils.isNotBlank(baseOrg.getDisLevel4())) {
                wrapper.eq("division_code", baseOrg.getDisLevel4()).eq("is_public", 0);
            } else if (StringUtils.isNotBlank(baseOrg.getDisLevel3())) {
                wrapper.eq("division_code", baseOrg.getDisLevel3()).eq("is_public", 0);
            } else if (StringUtils.isNotBlank(baseOrg.getDisLevel2())) {
                wrapper.eq("division_code", baseOrg.getDisLevel2() + "00").eq("is_public", 0);
            } else if (StringUtils.isNotBlank(baseOrg.getDisLevel1())) {
                wrapper.eq("division_code", baseOrg.getDisLevel1() + "0000").eq("is_public", 0);
            }
        } else if (idtIndicators.getIsPublic() == 1) {
            // 查询省级公共指标
            wrapper.eq("division_code", baseOrg.getDisLevel1() + "0000").eq("is_public", 1);
        } else if (idtIndicators.getIsPublic() == 2) {
            // 查询市级公共指标
            wrapper.eq("division_code", baseOrg.getDisLevel2() + "00").eq("is_public", 2);
            ;
        }*/
    }

    /**
     * @描述:查询指标数值
     * @入参:
     * @出参:
     * @作者: 郑文彬
     * @日期: 2020/6/29 12:00
     **/
    @PostMapping("/listIndicatorsValByCondition")
    @ApiOperation(value = "查询指标数值")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "code", value = "指标编码(多个用逗号隔开)", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "year", value = "年份(多个用逗号隔开)，year 和 startYear|endYear 二选一，只能填一个", required = false, dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "startYear", value = "起始年份，year 和 startYear|endYear 二选一，只能填一个", required = false, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "endYear", value = "结束年份，year 和 startYear|endYear 二选一，只能填一个", required = false, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "isReport", value = "环比是否计算上报值，不传默认false", required = false, dataType = "Boolean", paramType = "query"),
            @ApiImplicitParam(name = "area_code", value = "区域代码(多个用逗号隔开)", required = true, dataType = "string", paramType = "query")
    })
    public AjaxResult<List<ApiIndicatorsVal>> listIndicatorsValByCondition(String code, String year, String startYear, String endYear, String area_code, Boolean isReport) {
        // 根据指标编码去查指标
        LambdaQueryWrapper<IdtIndicators> queryWrapper = (new QueryWrapper()).lambda();
        String[] codes = code.split(",");
        queryWrapper.in(IdtIndicators::getCode, codes);
        List<IdtIndicators> list = idtIndicatorsService.list(queryWrapper);
        if (list == null || list.isEmpty()) {
            return new AjaxResult(new ArrayList<>(0));
        }
        // 获取指标id
        Set<String> idtIdSet = list.stream().map(IdtIndicators::getId).collect(Collectors.toSet());
        LinkedList<String> idtIdList = new LinkedList<>(idtIdSet);
        List<ApiIndicatorsVal> apiIndicatorsVals = new ArrayList<>();
        // 查询数值
        if (StringUtils.isNotBlank(year) && StringUtils.isBlank(startYear) && StringUtils.isBlank(endYear)) {
            apiIndicatorsVals = idtIndicatorsService.listIdtVal(idtIdList, year, area_code, false, null == isReport ? false : isReport);
        }
        if (StringUtils.isBlank(year) && StringUtils.isNotBlank(startYear) && StringUtils.isNotBlank(endYear)) {
            apiIndicatorsVals = idtIndicatorsService.listIdtVal(idtIdList, startYear, endYear, area_code, false, null == isReport ? false : isReport);
        }
        if (apiIndicatorsVals != null && apiIndicatorsVals.size() > 0) {
            // 20210806 添加指标预警规则
            apiIndicatorsVals.parallelStream().forEach(apiIndicatorsVal -> {
                if (StringUtils.isNotBlank(apiIndicatorsVal.getWarnRuleConfig())) {
                    String warnStatus = iIdtIndicatorsService.updateWarnStatus(apiIndicatorsVal);
                    apiIndicatorsVal.setWarnStatus(warnStatus);
                } else {
                    apiIndicatorsVal.setWarnStatus("null,尚未配置规则");
                }
            });
        }
        return new AjaxResult(apiIndicatorsVals);
    }

    /**
     * @描述:查询指标数值
     * @入参:
     * @出参:
     * @作者: lzy
     * @日期: 2020/11/7 9:44
     **/
    @PostMapping("/listIndicatorsValById")
    @ApiOperation(value = "查询指标值")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "指标id", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "year", value = "年份(多个用逗号隔开)", required = true, dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "area_code", value = "区域代码(多个用逗号隔开)", required = true, dataType = "string", paramType = "query")
    })
    public AjaxResult listIndicatorsValByCode(String id, String year, String area_code) {
        if (StringUtils.isBlank(id)) {
            return new AjaxResult(StatusCode.ERROR_CODE_40005, "id不能为空");
        }
        IdtIndicators idtIndicators = idtIndicatorsService.getById(id);
        if (idtIndicators != null) {
            List<String> idList = new ArrayList<String>();
            if ("formula".equals(idtIndicators.getDatasource())) {
                if (StringUtils.isBlank(idtIndicators.getCalculateResult())) {
                    return new AjaxResult(StatusCode.ERROR_CODE_40005, "该复合指标请先配置计算公式");
                }
                LambdaQueryWrapper<IdtIndicators> queryWrapper = (new QueryWrapper()).lambda();
                queryWrapper.in(IdtIndicators::getCode, RegularUtils.extractString(idtIndicators.getCalculateResult()));
                List<IdtIndicators> indicators = idtIndicatorsService.list(queryWrapper);
                indicators = indicators.stream().map(fill -> {
                    int index = idtIndicators.getCalculateResult().indexOf(fill.getCode());
                    fill.setSortNum(index);
                    return fill;
                }).collect(Collectors.toList());
                indicators = indicators.stream().sorted(Comparator.comparing(IdtIndicators::getSortNum)).collect(Collectors.toList());
                idList = indicators.stream().map(IdtIndicators::getId).collect(Collectors.toList());
            }
            idList.add(id);
            return this.listByIds(StringUtils.join(idList.toArray(), ","), year, area_code);
        } else {
            return new AjaxResult();
        }
    }

    /**
     * @描述: 通过多个指标id查询指标数值
     * @入参:
     * @出参:
     * @作者: lzy
     * @日期: 2020/11/7 16:20
     **/
    public AjaxResult listByIds(String ids, String year, String area_code) {
        List<String> idList = Arrays.asList(ids.split(","));
        List<ApiIndicatorsVal> apiIndicatorsVals = idtIndicatorsService.listIdtVal(idList, year, area_code, false, false);
        if (apiIndicatorsVals != null && apiIndicatorsVals.size() > 0) {

            // 获取所有子单位，基础运维未提供
            Map<String, String> deptMap = idtIndicatorsService.getDeptNameMap();

            for (ApiIndicatorsVal apiIndicatorsVal : apiIndicatorsVals) {
                //处理责任单位多级中文名问题
                String dutyCodes = apiIndicatorsVal.getDutyCompany();
                if (StringUtils.isNotBlank(dutyCodes)) {
                    apiIndicatorsVal.setDutyCompany(idtIndicatorsService.getDeptNameStr(dutyCodes, deptMap));
                }

                //处理责任处室多级中文名问题
                String codes = apiIndicatorsVal.getDutyDepartment();
                if (StringUtils.isNotBlank(codes)) {
                    apiIndicatorsVal.setDutyDepartment(idtIndicatorsService.getDeptNameStr(codes, deptMap));
                }
            }
        }
        return new AjaxResult(apiIndicatorsVals);
    }

    /**
     * @描述: 更新指标监测值的更新状态
     * @入参:
     * @出参:
     * @作者: 代鹏刚
     * @日期: 2020/10/23 15:24
     **/
    @PostMapping("/updateStatus")
    @ApiOperation(value = "更新指标监测值的更新状态")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "indicatorsId", value = "指标ID(多个使用逗号隔开)", required = true, dataType = "string", paramType = "query")
    })
    public AjaxResult updateStatus(String indicatorsId) {
        idtIndicatorsService.updateStatus(indicatorsId);
        return new AjaxResult();
    }

    /**
     * @描述: 更新指标上报值的更新状态
     * @入参:
     * @出参:
     * @作者: 代鹏刚
     * @日期: 2020/11/7 16:14
     **/
    @PostMapping("/updateReportStatus")
    @ApiOperation(value = "更新指标上报值的更新状态")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "indicatorsId", value = "指标ID(多个使用逗号隔开)", required = true, dataType = "string", paramType = "query")
    })
    public AjaxResult updateReportStatus(String indicatorsId) {
        idtIndicatorsService.updateReportStatus(indicatorsId);
        return new AjaxResult();
    }

    /**
     * @描述:获取指标树状列表
     * @入参:
     * @出参:
     * @作者: 汤厚韬
     * @日期: 2020/12/30
     **/
    @PostMapping("/getIdtIndicatorsTree")
    @ApiOperation(value = "获取机构树状图")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "dirId", value = "指标目录id", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "name", value = "关键字搜索", dataType = "string", paramType = "query"),
    })
    public AjaxResult getIdtIndicatorsTree(String dirId, String name) {
        if (StringUtils.isBlank(dirId)) {
            return new AjaxResult(StatusCode.ERROR_CODE_40005, "指标目录dirId不能为空");
        }
        return new AjaxResult(idtIndicatorsService.getIdtIndicatorsTree(dirId, name));
    }

    /**
     * @描述:获取新增指标项编码
     * @入参:
     * @出参:
     * @作者: 汤厚韬
     * @日期: 2021/1/21
     **/
    @PostMapping("/getAddIdtIndicatorsCode")
    @ApiOperation(value = "获取新增指标项编码")
    public AjaxResult getAddIdtIndicatorsCode() {
        return new AjaxResult(idtIndicatorsService.getAddIdtIndicatorsCode());
    }


    /**
     * 2021-12-21 为了避免指标计算公式出现A=B+C，C=E+D这种链式的情况，所有复合指标禁止作为计算公式的因子 <br/><br/>
     * 同样的因子可以被引用多次到公式，只是因子不能再被配公式 <br/><br/>
     * 有可能一个因子b是模型算的，一个因子c是系统对接的，指标a=b+c就是自动算的<br/><br/>
     *
     * @param excludeIdtIds 要排除的指标id列表，多个用逗号隔开
     * @author 陈宏成
     * @date 2021-12-21
     */
    @PostMapping("/listNonCompositeIdts")
    @ApiOperation(value = "获取非复合指标，不分页")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "excludeIdtIds", value = "要排除的指标id列表，多个用逗号隔开", dataType = "string", paramType = "query"),
    })
    public AjaxResult listNonCompositeIdts(String excludeIdtIds) {
        List<String> excludeIdList = null;
        if (StringUtils.isNotBlank(excludeIdtIds)) {
            excludeIdList = Arrays.asList(excludeIdtIds.trim().split(","));
        }
        List<IdtIndicators> idtIndicators = this.idtIndicatorsService.listNonCompositeIdts(excludeIdList);
        return new AjaxResult(idtIndicators);
    }
}


